// PowerPointSink.h : Declaration and implementation of the CPowerPointSink

#pragma once
#include "resource.h"
#include "AddinLib_i.h"

using namespace ATL;
using namespace PowerPoint;

// CPowerPointSink
// PowerPoint calls event handlers using the DISPIDs hardcoded into the type library 
// Our JavaScript objects can be found only by name, not by ID, so this class acts as 
// wrapper, accepting events and forwarding them onto the JavaScript object.
class ATL_NO_VTABLE CPowerPointSink :
	public CComObjectRoot,
	public IDispatchImpl<EApplication, &__uuidof(EApplication), &__uuidof(__PowerPoint), /* wMajor = */ 2, /* wMinor = */ 9>
{
private:
	// This is the JavaScript object to which we need to forward the events
	CComDispatchDriver pJsObject;

public:
	CPowerPointSink()
	{
	}

	BEGIN_COM_MAP(CPowerPointSink)
		COM_INTERFACE_ENTRY(EApplication)
		COM_INTERFACE_ENTRY2(IDispatch, EApplication)
	END_COM_MAP()

	DECLARE_PROTECT_FINAL_CONSTRUCT()

	void SetJsObject(IDispatch *pJsObject) {
		this->pJsObject = pJsObject;
	}

	HRESULT FinalConstruct()
	{
		return S_OK;
	}

	void FinalRelease()
	{
	}

private: 
	HRESULT Forward(LPCOLESTR eventName, IDispatch *pDispArg) { 
		CComVariant arg(pDispArg);
		HRESULT hr = pJsObject.Invoke1(eventName, &arg);
		
		// returning an error here seems to stop the propagation of further
		// events, so we always return success.
		return S_OK;
	}

	// EApplication Methods
public:
	STDMETHOD(WindowSelectionChange)(Selection * pSelection) {
		return Forward(L"WindowSelectionChange", pSelection);
	}

	STDMETHOD(WindowBeforeRightClick)(Selection * Sel, VARIANT_BOOL * Cancel)
	{
		return S_OK;
	}
	STDMETHOD(WindowBeforeDoubleClick)(Selection * Sel, VARIANT_BOOL * Cancel)
	{
		return S_OK;
	}
	STDMETHOD(PresentationClose)(_Presentation * Pres)
	{
		return S_OK;
	}
	STDMETHOD(PresentationSave)(_Presentation * Pres)
	{
		return S_OK;
	}
	STDMETHOD(PresentationOpen)(_Presentation * Pres)
	{
		return S_OK;
	}
	STDMETHOD(NewPresentation)(_Presentation * Pres)
	{
		return S_OK;
	}
	STDMETHOD(PresentationNewSlide)(_Slide * Sld)
	{
		return S_OK;
	}
	STDMETHOD(WindowActivate)(_Presentation * Pres, DocumentWindow * Wn)
	{
		return S_OK;
	}
	STDMETHOD(WindowDeactivate)(_Presentation * Pres, DocumentWindow * Wn)
	{	
		return S_OK;
	}
	STDMETHOD(SlideShowBegin)(SlideShowWindow * Wn)
	{
		return S_OK;
	}
	STDMETHOD(SlideShowNextBuild)(SlideShowWindow * Wn)
	{
		return S_OK;
	}
	STDMETHOD(SlideShowNextSlide)(SlideShowWindow * Wn)
	{
		return S_OK;
	}
	STDMETHOD(SlideShowEnd)(_Presentation * Pres)
	{
		return S_OK;
	}
	STDMETHOD(PresentationPrint)(_Presentation * Pres)
	{
		return S_OK;
	}
	STDMETHOD(SlideSelectionChanged)(SlideRange * SldRange)
	{
		return S_OK;
	}
	STDMETHOD(ColorSchemeChanged)(SlideRange * SldRange)
	{
		return S_OK;
	}
	STDMETHOD(PresentationBeforeSave)(_Presentation * Pres, VARIANT_BOOL * Cancel)
	{
		return S_OK;
	}
	STDMETHOD(SlideShowNextClick)(SlideShowWindow * Wn, Effect * nEffect)
	{
		return S_OK;
	}
	STDMETHOD(AfterNewPresentation)(_Presentation * Pres)
	{
		return S_OK;
	}
	STDMETHOD(AfterPresentationOpen)(_Presentation * Pres)
	{
		return S_OK;
	}
	STDMETHOD(PresentationSync)(_Presentation * Pres, MsoSyncEventType SyncEventType)
	{
		return S_OK;
	}
	STDMETHOD(SlideShowOnNext)(SlideShowWindow * Wn)
	{
		return S_OK;
	}
	STDMETHOD(SlideShowOnPrevious)(SlideShowWindow * Wn)
	{
		return S_OK;
	}
};

